package tetris.agent;

import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;

public class Matrix 
{
    // Extremely basic matrix math follows
    
	public static void write(BufferedWriter writer, double[] v)
	{
    	for(int i = 0; i < v.length; i++)
    	{
    		try
    		{
				writer.append(Double.toString(v[i]) + " ");
			} 
    		catch (IOException e)
    		{
				e.printStackTrace();
			}

    	}
	}
	
    // Prints v
    public static void print(double[] v)
    {
    	for(int i = 0; i < v.length; i++)
    	{
    		System.out.printf("%4.3f ", v[i]);
    	}
    		
    }
    
    // Prints M
    public static void print(double[][] M)
    {
    	for(int i = 0; i < M.length; i++)
    	{
    		for(int j = 0; j < M[0].length; j++)
    		{
    			System.out.printf("%4.3f ", M[i][j]);
    		}
    		System.out.printf("\n");
    	}
    	
    }
    
    // Fills the matrix with random doubles
    public static void rand(double[][] M)
    {
        for(int r = 0; r < M.length; r++)
        {
                for(int c = 0; c < M[0].length; c++)
                {
                        M[r][c] = Math.random();
                }
        }
    }
    
    // Fills the vector with random doubles
    public static void rand(double[] v)
    {
    	for(int i = 0; i < v.length; i++)
    	{
    		v[i] = Math.random();
    	}
    		
    }
    
    // Inflates the diagonal of M by d
    public static void inflate(double[][] M, double d)
    {
        for(int r = 0; r < M.length; r++)
        {
        	M[r][r] += d;
        }
    }
    
    // fills M with vectors v1 * v2'
    public static void outerProduct(double[][] M, double[] v1, double[] v2)
    {
            for(int r = 0; r < M.length; r++)
            {
                    for(int c = 0; c < M[0].length; c++)
                    {
                            M[r][c] = v1[r] * v2[c];
                    }
            }
    }
    
    // fills S with the subtraction of v1 and v2
    public static void sub(double[] S, double[] v1, double[] v2)
    {

            for(int i = 0; i < v1.length; i++)
            {
                    S[i] = v1[i] - v2[i];
            }
    }
    
    
    // fills S with the sum of v1 and v2
    public static void add(double[][] S, double[][] v1, double[][] v2)
    {

            for(int i = 0; i < v1.length; i++)
            {
                    for(int j =0 ; j < v1[0].length; j++)
                    {
                            S[i][j] = v1[i][j] + v2[i][j];
                    }
            }
    }
    
    
    // fills S with the sum of v1 and v2
    public static void add(double[] S, double[] v1, double[] v2)
    {

            for(int i = 0; i < v1.length; i++)
            {
                    S[i] = v1[i] + v2[i];
            }
    }
    
    // Returns the dot product of v1 and v2
    public double dot(double[] v1, double[] v2)
    {
            double toReturn = 0;
            for(int i = 0; i < v1.length; i++)
            {
                    toReturn += v1[i] * v2[i];
            }
                    
            return toReturn;
    }
    
    // Scales the matrix M by a
    public static void scale(double[][] M, double a)
    {
            for(int i = 0; i < M.length; i++)
            {
                    for(int j = 0; j < M[0].length; j++)
                    {
                            M[i][j] *= a;
                    }
            }
    }
    
    // Scales the vector v by a
    public static void scale(double[] v, double a)
    {
            for(int i = 0; i < v.length; i++)
            {
                    v[i] *= a;
            }
    }
    
    // copies B into A, assuming a and b are the same length.
    public static void copy(double[] a, double[] b)
    {
            for(int i = 0; i < a.length; i++)
            {
                    a[i] = b[i];
            }
    }
    
    
    // copies B into A, assuming a and b are the same length.
    public static void copy(double[][] a, double[][] b)
    {
            for(int i = 0; i < a.length; i++)
            {
                    for(int j = 0; j < a[0].length; j++)
                    {
                            a[i][j] = b[i][j];
                    }
            }
    }
    
}
